package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ExportExplainPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.ExcelTemplateDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.service.HandleImportService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.webimport.LinkFormImportPojo;
import com.xbongbong.saas.constant.export.ImportConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.KnowledgeDataEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.model.DataDictionaryModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/08/03 15:17
 */
@Component
public class ExportExcelExplainHelp {

    private static final Logger LOG = LoggerFactory.getLogger(ExportExcelExplainHelp.class);

    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private HandleImportService handleImportService;
    @Resource
    private DataDictionaryModel dataDictionaryModel;


    public ExportExplainPojo getExportExplain(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        List<FieldAttrEntity> headList = formDataListVO.getHeadList();
        String corpid = formDataListDTO.getCorpid();
        Integer businessType = formDataListDTO.getBusinessType();
        PaasFormExplainEntity paasFormExplainEntity;
        PaasMenuEntity paasMenuEntity;
        List<FieldAttrEntityForImport> fieldAttr = new ArrayList<>();
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRICE_SET_PRODUCT.getCode())) {
            paasFormExplainEntity = new PaasFormExplainEntity();
            JSONArray fieldAttrList = importHelper.getFieldAttrList(corpid);
            paasFormExplainEntity.setExplains(fieldAttrList.toJSONString());
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.PRICE_SET_PRODUCT.getName());
        }else if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.WRITE_OFF_RECORD.getCode())){
            paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(businessType);
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.WRITE_OFF_RECORD.getName());
        }else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())){
            paasFormExplainEntity = new PaasFormExplainEntity();
            for (FieldAttrEntity fieldAttrEntity : headList){
                FieldAttrEntityForImport fieldAttrEntityForImport = new FieldAttrEntityForImport();
                BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityForImport);
                fieldAttr.add(fieldAttrEntityForImport);
            }
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getName());
        } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_OUTSTOCK.getCode())){
            paasFormExplainEntity = new PaasFormExplainEntity();
            for (FieldAttrEntity fieldAttrEntity : headList){
                FieldAttrEntityForImport fieldAttrEntityForImport = new FieldAttrEntityForImport();
                BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityForImport);
                fieldAttr.add(fieldAttrEntityForImport);
            }
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.WAIT_OUTSTOCK.getName());
        } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_PURCHASE.getCode())){
            Map<String, FieldAttrEntity> explainMap = new HashMap<>();
            paasFormExplainEntity = new PaasFormExplainEntity();
            for (FieldAttrEntity fieldAttrEntity : headList){
                FieldAttrEntityForImport fieldAttrEntityForImport = new FieldAttrEntityForImport();
                BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityForImport);
                fieldAttr.add(fieldAttrEntityForImport);
                explainMap.put(fieldAttrEntity.getAttr(),fieldAttrEntity);
            }
            formDataListVO.setExplainMap(explainMap);
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.WAIT_PURCHASE.getName());
        } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.SMART_REPLENISHMENT.getCode())){
            Map<String, FieldAttrEntity> explainMap = new HashMap<>();
            paasFormExplainEntity = new PaasFormExplainEntity();
            for (FieldAttrEntity fieldAttrEntity : headList){
                FieldAttrEntityForImport fieldAttrEntityForImport = new FieldAttrEntityForImport();
                BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityForImport);
                fieldAttr.add(fieldAttrEntityForImport);
                explainMap.put(fieldAttrEntity.getAttr(),fieldAttrEntity);
            }
            formDataListVO.setExplainMap(explainMap);
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.SMART_REPLENISHMENT.getName());
        }else if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.KNOWLEDGE_BASE.getCode())){
            paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(businessType);
            //获取表单解释
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            Iterator<? extends FieldAttrEntity> iterator = explainList.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                if (Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.CREATOR_ID.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.UPDATE_TIME.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.LABEL.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.UPDATE_ID.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.APPENDIX.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.BASE_INFO.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.OTHER_INFO.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), KnowledgeDataEnum.ADD_TIME.getAttr())) {
                    iterator.remove();
                    continue;
                }
            }
            paasFormExplainEntity.setExplains(JSONArray.toJSONString(explainList));
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.KNOWLEDGE_BASE.getName());
        } else if (Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.SLA_LOG.getCode())) {
            // sla日志导出直接使用列表接口返回的解释
            Map<String, FieldAttrEntity> explainMap = new HashMap<>();
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formDataListDTO.getFormId(), corpid);
            if (paasFormExplainEntity == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            for (FieldAttrEntity fieldAttrEntity : headList){
                FieldAttrEntityForImport fieldAttrEntityForImport = new FieldAttrEntityForImport();
                BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityForImport);
                fieldAttr.add(fieldAttrEntityForImport);
                explainMap.put(fieldAttrEntity.getAttr(),fieldAttrEntity);
            }
            paasFormExplainEntity.setExplains(JSON.toJSONString(headList));
            formDataListVO.setExplainMap(explainMap);
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setName(XbbRefTypeEnum.SLA_LOG.getName());
        } else {
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formDataListDTO.getFormId(), corpid);
            if (paasFormExplainEntity == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            Long menuId = paasFormExplainEntity.getMenuId();
            paasMenuEntity = paasMenuModel.getByKey(menuId, corpid);
            if (paasMenuEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
            }
            String menuName = paasMenuEntity.getName();
            if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_SEARCH.getCode())) {
                menuName = XbbRefTypeEnum.STOCK_SEARCH.getName();
            } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode())) {
                menuName = XbbRefTypeEnum.WARNING_SEARCH.getName();
            } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())) {
                menuName = XbbRefTypeEnum.GUARANTEE_SEARCH.getName();
            }
            paasMenuEntity.setName(menuName);
        }
        if (CollectionsUtil.isEmpty(fieldAttr)) {
            fieldAttr = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntityForImport.class);
        }
        return new ExportExplainPojo(paasFormExplainEntity, paasMenuEntity, fieldAttr);
    }

    /**
     * 处理下字段解释，如将必填字段加*处理，以及“待”系列的特殊处理
     * @param formDataListDTO
     * @param paasFormExplainEntity
     * @param fieldAttrList
     * @param excelTemplateDTO
     * @return
     * @throws XbbException
     */
    public ExportExplainPojo dealExplain(FormDataListDTO formDataListDTO, PaasFormExplainEntity paasFormExplainEntity, List<FieldAttrEntityForImport> fieldAttrList, ExcelTemplateDTO excelTemplateDTO) throws XbbException {
        Integer businessType = formDataListDTO.getBusinessType();
        if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())
                || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_PURCHASE.getCode())
                || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_OUTSTOCK.getCode())
                || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.SMART_REPLENISHMENT.getCode())){
            handleImportService.waitSeriesFields(fieldAttrList , formDataListDTO);
            formDataListDTO.setDistributorMark(paasFormExplainEntity.getDistributorMark());
        }else{
            fieldAttrList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntityForImport.class);
            formDataListDTO.setDistributorMark(paasFormExplainEntity.getDistributorMark());
        }
        // 处理关联新建表单
        if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            LinkFormImportPojo linkFormImportPojo = new LinkFormImportPojo();
            BeanUtil.copyProperties(formDataListDTO, linkFormImportPojo);
            linkFormImportPojo.setFieldAttrEntityForImportList(fieldAttrList);
            linkFormImportPojo.setFormImportOrExport(ImportConstant.FROM_EXPORT);
            handleImportService.handleLinkForm(linkFormImportPojo, paasFormExplainEntity.getDistributorMark());
        }
        //部分导出需要过滤一些没有被选择的字段start
        boolean partialExportFlag = null!=formDataListDTO.getExcelPartialExportPojo()
                && Objects.equals(formDataListDTO.getExcelPartialExportPojo().getPartialExport(),1);
        // 过滤不需要导入的字段
        handleImportService.filterUnExportFields(formDataListDTO.getCorpid(), fieldAttrList, formDataListDTO.getSaasMark(), ImportConstant.FROM_EXPORT, formDataListDTO.getBusinessType(), partialExportFlag);
        List<String> partialSelectAttrs = new ArrayList<>();
        if(partialExportFlag){
            //过滤没有被选择的字段
            partialSelectAttrs = formDataListDTO.getExcelPartialExportPojo().getPartialSelectAttrs();
            excelTemplateDTO.setPartialExport(null);
            List<String> finalPartialSelectAttrs = partialSelectAttrs;
            if (Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.QUOTATION.getCode())){
                //报价单要特殊处理报价编号导出时转化成报价单组号和版本号
                fieldAttrList.removeIf(entry -> !finalPartialSelectAttrs.contains(entry.getAttr()) && !Objects.equals(entry.getAttr(), QuotationEnum.GROUP_NUMBER.getAttr()) && !Objects.equals(entry.getAttr(),QuotationEnum.VERSION.getAttr()));
            }else {
                fieldAttrList.removeIf(entry -> !finalPartialSelectAttrs.contains(entry.getAttr()));
            }
        }
        //部分导出需要过滤一些没有被选择的字段end
        // 处理公有的需要转换的字段
        handleImportService.handleCommonNeedTransferFields(fieldAttrList,formDataListDTO);
        JSONArray dataExplain;
        if (Objects.equals(excelTemplateDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // SaaS字段解释特处理
            excelTemplateDTO.setFormImportOrExport(ImportConstant.FROM_EXPORT);
            handleImportService.changeFieldShowTypeForImport(excelTemplateDTO, fieldAttrList);
            dataExplain = handleImportService.handleSpecialExplain(fieldAttrList, excelTemplateDTO);
            if(partialExportFlag && Objects.equals(excelTemplateDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())){
                //批次保质期查询后置过滤没有被选择的字段
                List<String> finalPartialSelectAttrs = partialSelectAttrs;
                dataExplain.removeIf(entry -> !finalPartialSelectAttrs.contains(((JSONObject) JSONObject.toJSON(entry)).get("attr")));
            }
            if(partialExportFlag && (Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.CLUE_PUBLIC.getCode()) || Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode()))){
                //过滤前负责人字段
                if (!partialSelectAttrs.contains("preOwnerId")){
                    fieldAttrList.removeIf(entry -> Objects.equals(entry.getAttr(),"preOwnerId"));
                    List<FieldAttrEntityForImport> fieldAttrEntityForImports = JSONArray.parseArray(dataExplain.toString(),FieldAttrEntityForImport.class);
                    fieldAttrEntityForImports.removeIf(entry -> Objects.equals(entry.getAttr(),"preOwnerId"));
                    dataExplain = JSON.parseArray(JSON.toJSONString(fieldAttrEntityForImports));
                }
            }
            if (partialExportFlag && Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.WARNING_SEARCH.getCode())){
                //过滤预警查询里面的默认字段
                List<String> finalPartialSelectAttrs = partialSelectAttrs;
                fieldAttrList.removeIf(entry -> !finalPartialSelectAttrs.contains(entry.getAttr()));
                List<FieldAttrEntityForImport> fieldAttrEntityForImports = JSONArray.parseArray(dataExplain.toString(),FieldAttrEntityForImport.class);
                fieldAttrEntityForImports.removeIf(entry -> !finalPartialSelectAttrs.contains(entry.getAttr()));
                dataExplain = JSON.parseArray(JSON.toJSONString(fieldAttrEntityForImports));
            }
        } else {
            handleImportService.setTitleTag(fieldAttrList);
            dataExplain = JSON.parseArray(JSON.toJSONString(fieldAttrList));
        }
        //针对付款单和回款单导出需要对text_10做些特殊处理，把所有的单据类型都放到解释里面
        if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.PAY_SHEET.getCode())) {
            //此处因为是导出，所以要展示所有的付款单类型
            for (FieldAttrEntityForImport next : fieldAttrList) {
                if (Objects.equals(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), next.getAttr())) {
                    List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaySheetType(true);
                    next.setItems(itemList);
                }
            }
        }
        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntityForImport next : fieldAttrList) {
                if (Objects.equals(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), next.getAttr())) {
                    //此处因为是导出，所以要展示所有的回款单类型
                    List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaymentSheetType(true);
                    next.setItems(itemList);
                }
            }
        }
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode())) {
            // 导出客户跟进记录这边的跟进业务，增加一个销售线索的下拉
            try {
                for (FieldAttrEntityForImport next : fieldAttrList) {
                    if (Objects.equals(CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr(), next.getAttr())) {
                        SubFormPoJo subForm = next.getSubForm();
                        if (Objects.nonNull(subForm) && CollectionsUtil.isNotEmpty(subForm.getItems())) {
                            List<ItemPoJo> items = subForm.getItems().get(0).getItems();
                            items.add(new ItemPoJo(XbbRefTypeEnum.CLUE.getName(), XbbRefTypeEnum.CLUE.getCode()));
                        }
                        break;
                    }
                }
            } catch (Exception e) {
                LOG.error("导出客户跟进记录这边的跟进业务，增加一个销售线索的下拉报错：", e);
            }
        }
        return new ExportExplainPojo(fieldAttrList, dataExplain);
    }
}
